package com.pz.minioproxy;

import org.apache.commons.codec.digest.DigestUtils;

import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class BigFileUpload {


    /**
     * 文件分割为 0,1,2,3...
     * @param saveBlobPath 最后一位字符必须有斜杠
     */
    private static void splitFile(File sourceFile, String saveBlobPath) throws IOException {
        //定义分块文件的最大大小
        int maxBlobSize = 1024*1024*2;

        //获取分块文件数量
        int blobNum = (int) Math.ceil(sourceFile.length() * 1.0 / maxBlobSize);

        // 定义源文件流
        RandomAccessFile raf_r = new RandomAccessFile(sourceFile, "r");
        // 定义字节缓冲区
        byte [] bufferByte = new byte[1024];


        for (int i = 0; i < blobNum; i++) {
            System.out.printf("<<<<<< upload blob file %d <<<<<<<<\n", i);
            File blobFile = new File(saveBlobPath+i);
            blobFile.delete();
            // 定义分块文件流
            RandomAccessFile raf_rw = new RandomAccessFile(blobFile, "rw");
            int len;
            while ((len=raf_r.read(bufferByte)) != -1) {
                raf_rw.write(bufferByte,0, len);
                if(blobFile.length() >= maxBlobSize){
                    break;
                }
            }
            raf_rw.close();
        }
        raf_r.close();
        System.out.println("split file success !!!");
    }

    private static File mergeFile(String saveBlobPath, String output) throws IOException {
        File blobDir = new File(saveBlobPath);
        //列举出存储分块文件夹下面的所有分块文件
        List<File> blobFiles = Arrays.asList(blobDir.listFiles());

        //文件排序(按照文件名大小升序排序 0,1,2,3...)
        blobFiles.sort(Comparator.comparingInt(o -> Integer.parseInt(o.getName())));

        File targetFile = new File(output);
        RandomAccessFile raf_rw = new RandomAccessFile(targetFile, "rw");
        byte [] buffer = new byte[1024];
        for (File blobFile : blobFiles) {
            int len;
            RandomAccessFile raf_r = new RandomAccessFile(blobFile, "r");
            while ((len = raf_r.read(buffer)) != -1) {
                raf_rw.write(buffer, 0, len);
            }
            raf_r.close();
        }
        raf_rw.close();
        System.out.println("merge success !");
        return targetFile;
    }

    public static void main(String[] args) {
        try {
            File sourceFile = new File("C:\\Users\\86151\\Downloads\\dianshijia.rar");
            splitFile(sourceFile, "E:\\bigfile-split-merge-demo\\splitfile\\demo1\\");
            File targetFile = mergeFile("E:\\bigfile-split-merge-demo\\splitfile\\demo1", "E:\\bigfile-split-merge-demo\\merge\\demo1.rar");
            String sourceMd5 = DigestUtils.md5Hex(new FileInputStream(sourceFile));
            String targetMd5 = DigestUtils.md5Hex(new FileInputStream(targetFile));
            System.out.printf("md5 of source: %s\n", sourceMd5);
            System.out.printf("md5 of target: %s\n", targetMd5);
            System.out.println("is equal: "+sourceMd5.equals(targetMd5));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
